package com.abel.demo.config;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.io.Serializable;
import java.nio.charset.Charset;

/**
 * Author: Abel.lin
 * Date: Created in 2018/9/5 15:06
 * Company: Abel.Studio
 * Copyright: Copyright (c) 2017
 * Description:
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    private static String keyPrefix;

    @Value("${spring.cache.redis.key-prefix}")
    public void setKeyPrefix(String keyPrefix){
        this.keyPrefix = keyPrefix;
    }
    @Bean
    public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new FastJsonRedisSerializer<>(Object.class));
        template.setHashKeySerializer(new FastJsonRedisSerializer<>(Object.class));
        JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer();
        template.setValueSerializer(redisSerializer);
        template.setHashValueSerializer(redisSerializer);
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setKeySerializer(new FastJsonRedisSerializer<>(String.class));
        template.setHashKeySerializer(new FastJsonRedisSerializer<>(String.class));
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    private static class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
        private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
        private Class<T> clazz;
        public FastJsonRedisSerializer(Class<T> clazz) {
            this.clazz = clazz;
        }

        @Override
        public byte[] serialize(T t) throws SerializationException {
            if (t == null) {
                return new byte[0];
            }
            String key = keyPrefix + t;
            return key.getBytes(DEFAULT_CHARSET);
        }

        @Override
        public T deserialize(byte[] bytes) throws SerializationException {
            if (bytes == null || bytes.length <= 0) {
                return null;
            }
            String str = new String(bytes, DEFAULT_CHARSET);
            return (T) JSON.parseObject(str, clazz);
        }
    }
}
